package com.TT.ticket;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 基本卖票例子
 * 线程就是一个单独的资源类，没有任何附属的操作
 * 1.属性、方法
 */
public class SaleTicketDemo2 {


    public static void main(String[] args) {
        //并发：多线程操作同一个资源类   把资源类丢入线程
        Ticket1 ticket1 = new Ticket1();

        //@FunctionalInterface 函数式   jdk1.8  lambda表达式 (参数)->{代码}
        new Thread(() -> {
            for (int i = 1; i < 60; i++) ticket1.sale();
        }, "A").start();


        new Thread(() -> {
            for (int i = 1; i < 60; i++) ticket1.sale();


        }, "B").start();


        new Thread(() -> {
            for (int i = 1; i < 60; i++) ticket1.sale();


        }, "C").start();

    }

}


// Lock 三部曲

/**
 * 1. new ReentrantLock();
 * 2.lock.lock(); 加锁
 * 3.lock.unlock();  解锁
 */
class Ticket1 {
    //属性 方法
    private int number = 50;

    //默认是非公平锁      ReentrantLock 可重入锁
    Lock lock = new ReentrantLock();


    //卖票的方式
    public void sale() {


        lock.lock();  //加锁


        try {

            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "卖出了" + number-- + "票,剩余:" + number);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }


    }

}
/**
 * Synchroonized lock 区别
 *
 * 1.Synchroonized 内置的java关键字，Lock是一个java类
 * 2.Synchroonized 无法判断获取锁的状态，Lock可以判断是否获取到了锁
 * 3.Synchroonized 会自动释放锁，lock必须要手动释放锁，如果不释放锁，死锁
 * 4.Synchroonized 线程1（获得锁，阻塞），线程2（等待，傻傻的等）;Lock锁就不一定会等待下去 （lock.tryLock()）
 * 5.Synchroonized 可重入锁，不可以中断的，非公平；Lock,可重入锁，可以判断锁，非公平（可以自己设置）
 * 6.Synchroonized 适合锁少量的代码同步问题，Lock适合锁大量的同步代码
 *
 */
